package io.leo.leoutils;


import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 一个用于反射的工具类
 */
public class ReflectUtils {

    //通过反射设置Bean对象的属性
    public static void setProperty(Object bean,String name,Object value) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Method method = bean.getClass().getMethod(toSetterCase(name),value.getClass());
        method.invoke(bean,value);
    }

    //把属性名转换成setter
    private static String toSetterCase(String fieldName){
        return "set"+fieldName.replaceFirst(fieldName.substring(0,1),fieldName.substring(0,1).toUpperCase());
    }
    //把属性名转换成getter
    private static String toGetterCase(String fieldName){
        return "get"+fieldName.replaceFirst(fieldName.substring(0,1),fieldName.substring(0,1).toUpperCase());
    }

    //判断是否是getter或setter
    private static boolean isSetterCase(String fieldName){
        return fieldName.startsWith("set");
    }
    private static boolean isGetterCase(String fieldName){
        return fieldName.startsWith("get");
    }

    //把getter和setter转换成属性名
    private static String toFieldName(String setterOrGetter){
        String s = setterOrGetter.substring(3);
        return s.replaceFirst(s.substring(0,1),s.substring(0,1).toLowerCase());
    }

    //获取一个对象的所有属性
    public static Property getProperties(Class c){
        Property property = new Property();

        Method[] methods = c.getDeclaredMethods();
        for (int i=0;i<methods.length;i++){
            Method method = methods[i];
            String name = method.getName();
//            if (StringUtils.in(name,"getConstructor","getClass","getDexClassDefIndex"))continue;
            if (isGetterCase(name))
                property.putGetterAuto(toFieldName(name),method);
            else if (isSetterCase(name))
                property.putSetterAuto(toFieldName(name),method);
            else continue;
        }
        return property;
    }

    //获取泛型的真实类型
    public static Class getActualType(Class clz){
        return (Class) ((ParameterizedType) clz.getGenericSuperclass()).getActualTypeArguments()[0];
    }

    //下划线命名风格变驼峰命名法
    public static String underLineToCamelCase(String underLine){
        StringBuffer buf = new StringBuffer(underLine);
        while (true){
            int index = buf.indexOf("_");
            if (index==-1)break;
            char c = buf.charAt(index+1);
            if (c>='a'&&c<='z')
                buf.replace(index+1,index+1, String.valueOf((char) c-32));
            buf.delete(index,index+1);
        }
        return buf.toString();
    }

    //驼峰命名法变下划线命名法
    public static String camelCaseToUnderLine(String camelCase){
        StringBuffer buf = new StringBuffer();
        char[] bufchars = camelCase.toCharArray();
        for (int i=0;i<bufchars.length;i++){
            if (bufchars[i]>='A'&&bufchars[i]<='Z'){
                buf.append("_");
                char lowerbufchars = (char) (bufchars[i]+32);
                buf.append(lowerbufchars);
            }else
                buf.append(bufchars[i]);
        }
        return buf.toString();
    }

    public static <T> T getAnnotation(Class clz,Class annotationClz){
        return (T) clz.getAnnotation(annotationClz);
    }



    //读取Property的Callback
    public interface PropertyReadCallback{
        void onRead(String name,Method getter,Method setter);
    }
}

